package com.sxran.im.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.sxran.im.bean.*;
import com.sxran.im.dao.ImGroupInviteMapper;
import com.sxran.im.dao.ImGroupMapper;
import com.sxran.im.dao.ImUserGroupMapper;
import com.sxran.im.dao.ImUserMapper;
import com.sxran.im.feign.ImApiFeign;
import com.sxran.im.feign.dto.*;
import com.sxran.im.handler.*;
import com.sxran.im.info.ImGroup;
import com.sxran.im.info.ImGroupInvite;
import com.sxran.im.info.ImUser;
import com.sxran.im.info.ImUserGroup;
import com.sxran.im.sbean.*;
import com.sxran.im.service.GroupService;
import com.sxran.im.service.JWTService;
import com.sxran.im.service.UserGroupService;
import com.sxran.im.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户相关的接口：
 * 注册,登陆。
 */
@CrossOrigin(origins = "*")
@RestController
public class GroupController {
	@Resource
	private ImGroupMapper imGroupMapper;
	@Resource
	private ImUserGroupMapper imUserGroupMapper;
	@Resource
	private ImGroupInviteMapper imGroupInviteMapper;
	@Resource
	private ImApiFeign imApiFeign;
	@Resource
	private GroupService groupService;
	@Resource
	private UserGroupService userGroupService;
	@Resource
	private ImUserMapper imUserMapper;

	///////////////////////////////////////////////////////////
	////                      带有通知的接口
	////
	////////////////////////////////////////////////////////////
	/**
	 * 创建群聊
	 * @see CreateGroupCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/createGroup")
	public CommonResult<Boolean> createGroup(@RequestBody CreateGroupReqBody json){
		// 1. 创建群信息。
		ImGroup group = json.getGroup();
		String groupId = IdUtil.getSnowflakeNextIdStr();
		List<String> users = json.getUsers();
		// 建群
		group.setGroupId(groupId);
		group.setOnline(1 + CollectionUtil.size(users));
		imGroupMapper.insert(group);
		//  将人拉入群聊中。
		if (CollectionUtil.isNotEmpty(users)) {
			for (String user : users) {
				ImUserGroup userGroup = new ImUserGroup();
				userGroup.setUid(user);
				userGroup.setGid(groupId);
				userGroup.setCreate_time(new Date());
				userGroup.setRole("user");
				imUserGroupMapper.insert(userGroup);
			}
		}
		// 设置自己是管理员。
		String curUserId = json.getCurUserId(); // ImController.getCurUserId();
		ImUserGroup userGroup = new ImUserGroup();
		userGroup.setUid(curUserId);
		userGroup.setGid(groupId);
		userGroup.setCreate_time(new Date());
		userGroup.setRole("admin");
		imUserGroupMapper.insert(userGroup);
		users.add(curUserId);

		// 绑定群组
		UserBindGroupInputBean userBindGroupInputBean = new UserBindGroupInputBean();
		userBindGroupInputBean.setUserList( users );
		userBindGroupInputBean.setGroupList(Lists.newArrayList(groupId) );
		imApiFeign.bindGroupByUser(userBindGroupInputBean);
		// 发送消息
		CreateGroupDTO exitGroupDTO = new CreateGroupDTO(groupId);
		exitGroupDTO.setCurUserId(curUserId);
		exitGroupDTO.setMessage("欢迎加入新的群聊");
		imApiFeign.chatGroup(exitGroupDTO);
		//
		return CommonResult.success(true);
	}
	/**
	 * 修改群聊信息
	 * @see UpdateGroupInfoCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/updateGroup")
	public CommonResult<Boolean> updateGroup(@RequestBody ImGroup json){

		String groupId = json.getGroupId();
		String operator = json.getOperator();
		// 获取群聊的用户组信息。
		if (userGroupService.isAdmin(groupId,operator)) {
			imGroupMapper.updateById(json);
			// 发送消息
			CreateGroupDTO exitGroupDTO = new CreateGroupDTO(groupId);
			exitGroupDTO.setCurUserId(operator);
			exitGroupDTO.setMessage("修改群组信息");
			imApiFeign.chatGroup(exitGroupDTO);
			return CommonResult.success(true);
		}else{
			return CommonResult.error(10401,"您不是管理员");
		}
	}
	/**
	 * 解散群聊
	 * @see DisBandGroupCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/disBandGroup")
	public CommonResult<Boolean> disBandGroup(@RequestBody ExportGroupReqBody json){
		String groupId = json.getGroupId();
		String curUserId = json.getCurUserId();
		// 获取群聊的用户组信息。
		if (userGroupService.isAdmin(groupId,curUserId)) {
			imGroupMapper.deleteById(groupId);
			// 移除所有用户。
			List<ImUserGroup> imUserGroups = userGroupService.removeUser(groupId, null);
			// 通知所有群组的人
			DisBandGroupDTO exitGroupDTO = new DisBandGroupDTO(groupId);
			exitGroupDTO.setCurUserId(curUserId);
			exitGroupDTO.setMessage(json.getMessage());
			imApiFeign.chatGroup(exitGroupDTO);
			// 解绑群组
			UserUnbindGroupInputBean userBindGroupInputBean = new UserUnbindGroupInputBean();
			userBindGroupInputBean.setUserList( imUserGroups.stream().map(ImUserGroup::getUid).collect(Collectors.toList()) );
			userBindGroupInputBean.setGroupList( Lists.newArrayList(groupId) );
			imApiFeign.unbindGroupByUser(userBindGroupInputBean);
			return CommonResult.success(true);
		}else{
			return CommonResult.error(10401,"您不是管理员");
		}
	}
	/**
	 * 退出群聊
	 * @see ExitGroupCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/exitGroup")
	public CommonResult<Boolean> exitGroup(@RequestBody ExportGroupReqBody json){
		String groupId = json.getGroupId();
		String curUserId = json.getCurUserId();
		List<ImUserGroup> list = userGroupService.removeUser(groupId, Lists.newArrayList(curUserId));
		if( list.size() > 0 ){
			// 解绑群组
			UserUnbindGroupInputBean userBindGroupInputBean = new UserUnbindGroupInputBean();
			userBindGroupInputBean.setUserList( Lists.newArrayList(curUserId)  );
			userBindGroupInputBean.setGroupList( Lists.newArrayList(groupId) );
			imApiFeign.unbindGroupByUser(userBindGroupInputBean);
			// 发送消息
			ExitGroupDTO exitGroupDTO = new ExitGroupDTO(groupId);
			exitGroupDTO.setCurUserId(curUserId);
			exitGroupDTO.setMessage(json.getMessage());
			imApiFeign.chatGroup(exitGroupDTO);
			return CommonResult.success(true);
		}else{
			return CommonResult.error(10400,"退出群聊失效");
		}
	}
	/**
	 * 踢出群聊
	 * @see ExportGroupCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/kickOutGroup")
	public CommonResult<Boolean> kickOutGroup(@RequestBody ExportGroupReqBody json){
		String groupId = json.getGroupId();
		List<String> users = json.getUsers();
		String curUserId = json.getCurUserId();
		if(CollectionUtil.isEmpty(users)){
			return CommonResult.error(10400,"没有指定用户");
		}
		// 获取群聊的用户组信息。
		if (userGroupService.isAdmin(groupId,curUserId)) {
			// 移除用户。
			userGroupService.removeUser(groupId, users);
			// 提示用户被踢出群聊
			KickOutGroupDTO kickOutGroupDTO = new KickOutGroupDTO(groupId);
			kickOutGroupDTO.setContent(json.getMessage());
			kickOutGroupDTO.setOperator(curUserId);
			imApiFeign.batchChatUser(users,kickOutGroupDTO );
			// 解绑群组
			UserUnbindGroupInputBean userBindGroupInputBean = new UserUnbindGroupInputBean();
			userBindGroupInputBean.setUserList( users  );
			userBindGroupInputBean.setGroupList( Lists.newArrayList(groupId) );
			imApiFeign.unbindGroupByUser(userBindGroupInputBean);
			return CommonResult.success(true);
		}else{
			return CommonResult.error(10401,"您不是管理员");
		}
	}

	/**
	 * 拒绝进入群聊
	 *
	 * @see RefuseGroupApplicationCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/refuseGroup")
	public CommonResult<Boolean> refuseGroup(@RequestBody ImGroupInvite json){
		// 修改申请,通知的状态。
		groupService.updateState(json,-100);
		// 设置最新的用户信息。
		String fromUid = json.getUserId();
		String groupId = json.getGroupId();
		// 单独提示当前用户拒绝进入群聊的信息.
		RefuseGroupDTO acceptGroupDTO = new RefuseGroupDTO(groupId);
		acceptGroupDTO.setContent(json.getMessage()); // 拒绝的信息.
		imApiFeign.chatUser(fromUid,acceptGroupDTO);
		return CommonResult.success(true);
	}
	/**
	 * 同意进入群聊
	 * @see AcceptGroupApplicationCmdHandler
	 * @param json
	 * @return
	 */
	@PostMapping("/api/group/acceptGroup")
	public CommonResult<Boolean> acceptGroup(@RequestBody ImGroupInvite json){
// 修改申请,通知的状态。
		groupService.updateState(json,100);
		// 设置最新的用户信息。
		String fromUid = json.getUserId(); //json.getFromUid();
//        System.out.println("添加内容:"+ curUserId + "|" +fromUid );
//		ImUser imUser = userService.selectByUserId(fromUid);
//		acceptFriendApplicationHttpResp.setApplicationUserInfo(imUser);
		// 添加群聊记录。
		ImUserGroup imUserGroup = new ImUserGroup();
		String groupId = json.getGroupId();
		imUserGroup.setGid(groupId);
		imUserGroup.setUid(fromUid);
		imUserGroup.setCreate_time(new Date());
		imUserGroup.setRole("user");
		imUserGroupMapper.insert(imUserGroup);
		// 先提示所有人..
		NewMemberJoinGroupDTO groupDto = new NewMemberJoinGroupDTO(groupId);
		groupDto.setContent("有新成员加入群聊");
		imApiFeign.chatGroup(groupDto);
		// 绑定群组..
		UserBindGroupInputBean userBindGroupInputBean = new UserBindGroupInputBean();
		userBindGroupInputBean.setUserList( Lists.newArrayList(fromUid) );
		userBindGroupInputBean.setGroupList(Lists.newArrayList(groupId) );
		imApiFeign.bindGroupByUser(userBindGroupInputBean);
		// 单独提示当前用户进入群聊...
		AcceptGroupDTO acceptGroupDTO = new AcceptGroupDTO(groupId);
		acceptGroupDTO.setContent("欢迎加入群聊");
		imApiFeign.chatUser(fromUid,acceptGroupDTO);

		return CommonResult.success(true);
	}
	/**
	 * 申请进入群聊
	 * @see AddGroupInviteCmdHandler
	 * @param bean
	 * @return
	 */
	@PostMapping("/api/group/apply")
	public CommonResult<Boolean> apply(@RequestBody ImGroupInvite bean){
		String curUserId = ImController.getCurUserId();
		String groupId = bean.getGroupId();

		//
		LambdaQueryWrapper<ImUserGroup> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ImUserGroup::getGid,groupId);
		queryWrapper.eq(ImUserGroup::getUid,curUserId);
		if (imUserGroupMapper.exists(queryWrapper)) {
			return CommonResult.error(10025,"已经是成员");
		}
		// TODO 检查是不是黑名单...

		// 不存在就添加，存在就更新
		bean.setUserId(curUserId);

		LambdaQueryWrapper<ImGroupInvite> groupInviteWrapper = new LambdaQueryWrapper<>();
		groupInviteWrapper.eq(ImGroupInvite::getGroupId,groupId);
		groupInviteWrapper.eq(ImGroupInvite::getUserId,curUserId);
		ImGroupInvite imGroupInvite = imGroupInviteMapper.selectOne(groupInviteWrapper);
		if (imGroupInvite == null) {
			imGroupInvite = bean;
			imGroupInvite.setUpdateTime(new Date());
			imGroupInvite.setCreatTime(new Date());
			imGroupInvite.setState(0);
			imGroupInviteMapper.insert(imGroupInvite);
		}else{
			imGroupInvite.setState(0);
			imGroupInvite.setUpdateTime(new Date());
			imGroupInvite.setMessage(bean.getMessage());
			imGroupInviteMapper.update(imGroupInvite,groupInviteWrapper);
		}

		// 获取管理员
		LambdaQueryWrapper<ImUserGroup> notificationWrapper = new LambdaQueryWrapper<>();
		notificationWrapper.eq(ImUserGroup::getGid,groupId);
		notificationWrapper.eq(ImUserGroup::getRole,"admin");
		List<ImUserGroup> imUserGroups = imUserGroupMapper.selectList(notificationWrapper);
		// 通知管理员
		List<String> userIdArray = imUserGroups.stream().map(ImUserGroup::getUid).collect(Collectors.toList());
		ApplyGroupDTO applyGroupDTO = new ApplyGroupDTO(groupId);
		applyGroupDTO.setContent(bean.getMessage());
		imApiFeign.batchChatUser(userIdArray,applyGroupDTO );
		return  CommonResult.success(true);
	}


	///////////////////////////////////////////////////////////
	////		传统的im业务...
	////
	////////////////////////////////////////////////////////////
	/**
	 * 群聊的详细信息列表
	 * @see GetGroupInfoCmdHandler
	 * @param userId
	 * @return
	 */
	@PostMapping("/api/group/groupInfo")
	public CommonResult<Map<String, Object>> groupInfo(@RequestParam("userId") String userId,@RequestParam("groupId") String groupId){
//		String groupId = json.getGroupId();
		String curUserId =  userId;//ImController.getCurUserId();
		ImGroup imGroup = imGroupMapper.selectById(groupId);
		Map<String, Object> objectMap = BeanUtil.beanToMap(imGroup);
		objectMap.put("isAdmin",false);
		// 获取群聊的用户组信息。
		LambdaQueryWrapper<ImUserGroup> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ImUserGroup::getGid,groupId);
		List<ImUserGroup> imUserGroups = imUserGroupMapper.selectList(queryWrapper);
		int size = imUserGroups.size();
		//
		List<Map<String, Object>> memberList = new ArrayList<>(size);
		for (int i = 0; i < size; i++) {
			ImUserGroup imUserGroup = imUserGroups.get(i);
			String uid = imUserGroup.getUid();
			ImUser imUser = imUserMapper.selectById(uid);
			Map<String, Object> userMap = BeanUtil.beanToMap(imUser);
			String role = imUserGroup.getRole();
			userMap.put("role", role);
			// 当前用户是不是管理员逻辑。
			if (curUserId.equals(uid) && "admin".equals(role) ) {
				objectMap.put("isAdmin",true);
			}
			//
			memberList.add(userMap);
		}
		//
		objectMap.put("memberList",memberList);
		return CommonResult.success(objectMap);
	}
	/**
	 * 我的群聊列表
	 * @see GetGroupListCmdHandler
	 * @param userId
	 * @return
	 */
	@PostMapping("/api/group/myGroups")
	public CommonResult<List<ImGroup>> myGroups(@RequestParam("userId") String userId){
		//
//		String userId = ImController.getCurUserId();
		// 群组
		List<ImUserGroup> imUserGroups = userGroupService.selectList(userId);
		//
		List<ImGroup> groups = imUserGroups.stream().map(x -> imGroupMapper.selectById(x.getGid())).collect(Collectors.toList());
		return CommonResult.success(groups);
	}


	/**
	 * @see SearchGroupListHandler
	 * @param group
	 * @return
	 */
	@PostMapping("/api/group/search")
	public CommonResult<List<ImGroup>> search(@RequestBody ImGroup group){
		LambdaQueryWrapper<ImGroup> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ImGroup::getGroupId,  group.getGroupId() ); // 强关联 id
		queryWrapper.like(ImGroup::getName,  group.getName() );   // 搜索昵称
		queryWrapper.like(ImGroup::getIntroduction,  group.getIntroduction() );   // 搜索简介
		List<ImGroup> imGroups = imGroupMapper.selectList(queryWrapper);
		return  CommonResult.success(imGroups);
	}

}
